use super::MutexValue;

pub struct Arc<OPEN: Fn(), CLOSE: Fn()> {
    count: MutexValue<u32>,
    open_fn: OPEN,
    close_fn: CLOSE,
}

impl<OPEN: Fn(), CLOSE: Fn()> Arc<OPEN, CLOSE> {
    pub const fn uninit(open: OPEN, close: CLOSE) -> Self {
        Self {
            count: MutexValue::uninit(0),
            open_fn: open,
            close_fn: close,
        }
    }

    pub unsafe fn init_once(&self, name: &'static str) {
        self.count.init_once(name);
    }

    pub fn open(&self) {
        let mut count = self.count.lock();
        let n = *count;
        *count = n + 1;
        drop(count);

        if n == 1 {
            (self.open_fn)();
        }
    }

    pub fn close(&self) {
        let mut count = self.count.lock();
        let n = *count;
        if n == 0 {
            return;
        }
        *count = n - 1;
        drop(count);
        if n == 1 {
            (self.close_fn)();
        }
    }

    pub fn force_close(&self) {
        let mut count = self.count.lock();
        *count = 0;
        drop(count);
        (self.close_fn)();
    }
    
}
